/*
 * @Author: 0x9DEFA478
 * @Date: 2021-07-18 20:42:32
 * @LastEditTime: 2021-07-25 00:15:46
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * QQ:2652450237
 * ============================================================================================================================================
 * 
 * 
 * 
 *                                                                                               ************      ****************************
 *                                                                                             ************      ****************************  
 *                                                                                           ************      ****************************    
 *                                                                                         ************      ****************************      
 *                                                                                       ************      ************                        
 *                                                                                     ************      ************                          
 *                                                                                   ************      ************                            
 *                                                                                 ************      ************                              
 *                                                                               ************      ************                                
 *                                                                             ************      ************                                  
 *                                                                           ************      ************                                    
 *                                                                         ************      ************                                      
 *                                                                       ************      ************                                        
 *                                                                     ************      ************                                          
 *                                                                   ************      ************                                            
 *                                                                 ************      ************                                              
 *                                                               ************      ************                                                
 *                                                             ************      ************                                                  
 *                                                           ************      ************                                                    
 *                                                         ************      ************                                                      
 *                                                       ************      ************                                                        
 *                                                     ************      ************                                                          
 *                                                   ************      ************                                                            
 *                                                 ************      ************                                                              
 *                                               ************      ************                                                                
 *                                             ************      ************                                                                  
 *                                           ************      ************                                                                    
 *                                         ************      ************                                                                      
 *                                       ************      ************                                                                        
 *                                     ************      ************                                                                          
 *                                   ************      ************                                                                            
 *                                 ************      ************                                                                              
 *                               ************      ************                                                                                
 *                             ************      ************                                                                                  
 *                           ************      ************                                                                                    
 *                         ************      ************                                                                                      
 *       ****************************      ************                                                                                        
 *     ****************************      ************                                                                                          
 *   ****************************      ************                                                                                            
 * ****************************      ************                                                                                              
 * 
 * 
 * 
 * ============================================================================================================================================
 * 
 */
#include "H_StringItem.h"



/**
 * 
 * 以下各个方法需保证互斥调用(一个方法调用完成之后才能调用其他方法(回调导致的不在此范围)) 
 * 
 */


/**
 * @brief 新建一个 H_StringItem
 * @param DrawString 绘制字符串方法
 * @param Malloc 获取内存方法
 * @param Free 释放内存方法
 * @return H_StringItem 指针
 */
H_StringItem* new_H_StringItem(void (*DrawString)(char* String,void* Font,int Status,int X,int Y,int MaxX,int MaxY)
  ,void* (*Malloc)(Husize),void (*Free)(void*)){
  H_StringItem* StringItem;

  StringItem=Malloc(sizeof(H_StringItem));

  if(StringItem==NULL){
    return NULL;
  }

  StringItem->DrawString=DrawString;

  StringItem->Malloc=Malloc;
  StringItem->Free=Free;

  return StringItem;
}

/**
 * @brief 新建一个链表
 * @param StringItem H_StringItem对象
 * @param X X坐标
 * @param Y Y坐标
 * @param Width 宽度
 * @param Height 高度
 * @return H_StringItem_List 对象
 */
H_StringItem_List* new_H_StringItem_List(H_StringItem* StringItem,int X,int Y,int Width,int Height){
  H_StringItem_List* StringItem_List;
  
  StringItem_List=StringItem->Malloc(sizeof(H_StringItem_List));

  StringItem_List->Malloc=StringItem->Malloc;
  StringItem_List->Free=StringItem->Free;
  StringItem_List->X=X;
  StringItem_List->Y=Y;
  StringItem_List->Width=Width;
  StringItem_List->Height=Height;
  StringItem_List->isSelect=0;
  StringItem_List->ExitCallback=NULL;

  StringItem_List->Items=NULL;
  StringItem_List->HighLightItem=NULL;

  return StringItem_List;
}

/**
 * @brief 添加列表项
 * @param StringItem_List 要添加到的列表
 * @param Height 项高度 要小于等于列表(H_StringItem_List)的高度
 * @return H_StringItem_ListItem对象
 */
H_StringItem_ListItem* H_StringItem_List_AddItem(H_StringItem_List* StringItem_List,int Height){
  H_StringItem_ListItem* StringItem_ListItem;
  H_StringItem_ListItem* p;

  StringItem_ListItem=StringItem_List->Malloc(sizeof(H_StringItem_ListItem));

  StringItem_ListItem->Parent=StringItem_List;

  StringItem_ListItem->String=NULL;
  StringItem_ListItem->StringMemSize=0;
  StringItem_ListItem->Font=NULL;
  StringItem_ListItem->Height=Height;
  
  StringItem_ListItem->AddClickCallback=NULL;
  StringItem_ListItem->SubClickCallback=NULL;
  StringItem_ListItem->SelectCallback=NULL;
  StringItem_ListItem->DeSelectCallback=NULL;

  StringItem_ListItem->List.Next=NULL;

  p=StringItem_List->Items;

  if(p==NULL){
    StringItem_ListItem->List.Last=NULL;
    StringItem_List->Items=StringItem_ListItem;
    StringItem_List->HighLightItem=StringItem_ListItem;
  }else{
    while(p->List.Next!=NULL){
      p=p->List.Next;
    }
    p->List.Next=StringItem_ListItem;

    StringItem_ListItem->List.Last=p;
    p->List.Next=StringItem_ListItem;

  }

  if(StringItem_List->Items==NULL){
    StringItem_List->Items=StringItem_ListItem;
    StringItem_List->HighLightItem=StringItem_ListItem;
  }

  return StringItem_ListItem;
}

/**
 * @brief 删除H_StringItem (仅删除StringItem本身)
 * @param StringItem 要删除的对象
 * @return 无
 */
void delete_H_StringItem(H_StringItem* StringItem){
  StringItem->Free(StringItem);
}

/**
 * @brief 删除列表 会将其中的项删除 在StringItem_List从移除之后才能使用此方法
 * @param StringItem_List 要删除的列表
 * @return 无
 */
void delete_H_StringItem_List(H_StringItem_List* StringItem_List){
  H_StringItem_ListItem* p;
  H_StringItem_ListItem* p_next;

  p=StringItem_List->Items;

  while(p->List.Last!=NULL){
    p=p->List.Last;
  }
  
  while(p!=NULL){
    p_next=p->List.Next;
    if(p->String!=NULL){
      StringItem_List->Free(p->String);
    }
    StringItem_List->Free(p);
    p=p_next;
  }
  
  StringItem_List->Free(StringItem_List);
}

/**
 * @brief 设置H_StringItem正在使用的列表
 * @param StringItem 要设置的H_StringItem
 * @param List 需要设置成的列表
 * @return 无
 */
void H_StringItem_SetList(H_StringItem* StringItem,H_StringItem_List* List){

  StringItem->NowList=List;
}

/**
 * @brief 设置项的字符串
 * @param Item 要设置的项
 * @param String 字符串
 * @return noEdit
 */
void H_StringItem_SetString(H_StringItem_ListItem* Item,char* String){
  H_StringItem_List* StringItem_List;
  int Length;

  StringItem_List=Item->Parent;

  Length=0;
  while(String[Length]!='\0'){
    Length++;
  }

  Length+=1;

  if(Item->String==NULL){
    Item->String=StringItem_List->Malloc(Length);
    Item->StringMemSize=Length;
  }else{
    if(Item->StringMemSize<Length){
      StringItem_List->Free(Item);
      Item->String=StringItem_List->Malloc(Length);
      Item->StringMemSize=Length;
    }
  }

  while(Length){
    Length--;
    Item->String[Length]=String[Length];
  }

}

/**
 * @brief 设置项的字体
 * @param Item 要设置的项
 * @param Font 字体
 * @return 无
 */
void H_StringItem_SetFont(H_StringItem_ListItem* Item,void* Font){
  Item->Font=Font;
}




/**
 * @brief 发生确认事件时 调用此方法
 * @param StringItem H_StringItem
 * @return 无
 */
void H_StringItem_EventEnter(H_StringItem* StringItem){
  H_StringItem_List* List;

  List=StringItem->NowList;

  if(List==NULL){
    return;
  }
	if(List->Items==NULL){
    return;
  }

  if(StringItem->NowList->isSelect==0){
    StringItem->NowList->isSelect=-1;
		if(StringItem->NowList->HighLightItem->SelectCallback!=NULL){
			StringItem->NowList->HighLightItem->SelectCallback(StringItem->NowList->HighLightItem);
		}
  }
  
}

/**
 * @brief 发生返回事件时 调用此方法
 * @param StringItem H_StringItem
 * @return 无
 */
void H_StringItem_EventBack(H_StringItem* StringItem){
  H_StringItem_List* List;

  List=StringItem->NowList;

  if(List==NULL){
    return;
  }
	if(List->Items==NULL){
    return;
  }

  if(StringItem->NowList->isSelect!=0){
    StringItem->NowList->isSelect=0;
		if(StringItem->NowList->HighLightItem->DeSelectCallback!=NULL){
			StringItem->NowList->HighLightItem->DeSelectCallback(StringItem->NowList->HighLightItem);
		}
  }else{
		if(StringItem->NowList->ExitCallback!=NULL){
			StringItem->NowList->ExitCallback(StringItem->NowList);
		}
  }
}

/**
 * @brief 发生增加事件时 调用此方法
 * @param StringItem H_StringItem
 * @return 无
 */
void H_StringItem_EventAdd(H_StringItem* StringItem){
  H_StringItem_List* List;
  H_StringItem_ListItem* Item;
  int height;

  List=StringItem->NowList;

  if((List==NULL)||(List->Items==NULL)){
    return;
  }

  if(List->isSelect!=0){
		if(List->HighLightItem->AddClickCallback!=NULL){
			List->HighLightItem->AddClickCallback(List->HighLightItem);
		}
  }else{

    Item=List->HighLightItem;
    if(Item->List.Next!=NULL){
      List->HighLightItem=Item->List.Next;//切换到下一个项

      Item=List->Items;
      height=0;
      while((Item!=List->HighLightItem)&&(height<List->Height)){
        Item=Item->List.Next;
        height+=Item->Height;
      }
      height+=List->HighLightItem->Height;
      
      Item=List->Items;
      while(height>List->Height){
        height-=Item->Height;
        Item=Item->List.Next;
      }
      List->Items=Item;

    }
  }
}

/**
 * @brief 发生减少事件时 调用此方法
 * @param StringItem H_StringItem
 * @return 无
 */
void H_StringItem_EventSub(H_StringItem* StringItem){
  H_StringItem_List* List;
  H_StringItem_ListItem* Item;

  List=StringItem->NowList;

  if((List==NULL)||(List->Items==NULL)){
    return;
  }

  if(StringItem->NowList->isSelect!=0){
		if(StringItem->NowList->HighLightItem->SubClickCallback!=NULL){
			StringItem->NowList->HighLightItem->SubClickCallback(StringItem->NowList->HighLightItem);
		}
  }else{
    
    Item=List->HighLightItem;
    if(Item->List.Last!=NULL){
      if(List->Items==List->HighLightItem){
        List->Items=Item->List.Last;
      }
      List->HighLightItem=Item->List.Last;//切换到上一个项
      
    }

  }
}


/**
 * @brief 绘制字符串
 * @param StringItem StringItem对象
 * @return 无
 */
void H_StringItem_Draw(H_StringItem* StringItem){
  H_StringItem_List* List;
  H_StringItem_ListItem* Item;
  int height;
  int Status;
  int X;
  int Y;

  List=StringItem->NowList;

  if(List!=NULL){
    Item=List->Items;

    height=Item->Height;
    while((Item!=NULL)&&(height<=List->Height)){

      if((Item->String!=NULL)&&(Item->Font!=NULL)){

        Status=vH_StringItem_Status_Default;
        if(List->HighLightItem==Item){
          Status=vH_StringItem_Status_HighLight;
          if(List->isSelect!=0){
            Status=vH_StringItem_Status_Select;
          }
        }

        X=List->X;
        Y=List->Y+height - Item->Height;

        StringItem->DrawString(Item->String,Item->Font,Status,X,Y,X+List->Width-1,Y+Item->Height-1);
      }
      
      Item=Item->List.Next;
      height+=Item->Height;
    }
  }

}




